/*
 * drivers/video/fbdev/sunxi/disp2/disp/de/lowlevel_v3x/de_dsi_28/de_dsi_28.c
 *
 * Copyright (c) 2007-2017 Allwinnertech Co., Ltd.
 * Author: zhengxiaobin <zhengxiaobin@allwinnertech.com>
 *
 * mipi-dsi lowlevel driver for 28nm version
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */
#include "../tcon_feat.h"
#include "de_dsi_type_28.h"
#include "de_dsi.h"

#if defined(SUPPORT_DSI)

u32 dsi_bits_per_pixel[4] = {24, 24, 18, 16};
u32 dsi_pixel_bits[4] = {24, 24, 18, 16};
u32 dsi_lane_den[4] = {0x1, 0x3, 0x7, 0xf};
u32 tcon_div = 4;

static volatile __de_dsi_dev_t *dsi_dev[DEVICE_DSI_NUM];

s32 dsi_delay_ms(u32 ms)
{
	disp_delay_ms(ms);

	return 0;
}

s32 dsi_delay_us(u32 us)
{
	disp_delay_us(us);

	return 0;
}

__s32 dsi_set_reg_base(__u32 sel, uintptr_t base)
{
	dsi_dev[sel] = (__de_dsi_dev_t *)(base);

	return 0;
}

__u32 dsi_get_reg_base(__u32 sel)
{
	return (uintptr_t)dsi_dev[sel];
}

__u32 dsi_get_start_delay(__u32 sel)
{
	return 0;
}

__u32 dsi_get_cur_line(__u32 sel)
{
	return 0;
}

__s32 dsi_irq_enable(__u32 sel, enum __dsi_irq_id_t id)
{
	if (id < 32) {
		dsi_dev[sel]->dsi_irq_en0.dwval &= ~(1 << id);
	} else {
		dsi_dev[sel]->dsi_irq_en1.dwval &= ~(1 << (id - 32));
	}
	return 0;
}

__s32 dsi_irq_disable(__u32 sel, enum __dsi_irq_id_t id)
{
	if (id < 32) {
		dsi_dev[sel]->dsi_irq_en0.dwval |= (1 << id);
	} else {
		dsi_dev[sel]->dsi_irq_en1.dwval |= (1 << (id - 32));
	}
	return 0;
}

static __s32 dsi_irq_disable_all(__u32 sel)
{
	dsi_dev[sel]->dsi_irq_en0.dwval = 0xffffffff;
	dsi_dev[sel]->dsi_irq_en1.dwval = 0xffffffff;
	return 0;
}

__u32 dsi_irq_query(__u32 sel, enum __dsi_irq_id_t id)
{
	return 0;
}

__s32 dsi_inst_busy(__u32 sel)
{
	return 0;
}

__s32 dsi_start(__u32 sel, enum __dsi_start_t func)
{
	return 0;
}

__s32 dsi_open(__u32 sel, disp_panel_para *panel)
{
	if (panel->lcd_dsi_if == LCD_DSI_IF_COMMAND_MODE) {
		dsi_dev[sel]->dsi_cmd_ctl.bits.gen_sw_0p_tx_lp = 0;
		dsi_dev[sel]->dsi_cmd_ctl.bits.gen_sw_1p_tx_lp = 0;
		dsi_dev[sel]->dsi_cmd_ctl.bits.gen_sw_2p_tx_lp = 0;
		dsi_dev[sel]->dsi_cmd_ctl.bits.gen_sr_0p_tx_lp = 0;
		dsi_dev[sel]->dsi_cmd_ctl.bits.gen_sr_1p_tx_lp = 0;
		dsi_dev[sel]->dsi_cmd_ctl.bits.gen_sr_2p_tx_lp = 0;
		dsi_dev[sel]->dsi_cmd_ctl.bits.dcs_sw_0p_tx_lp = 0;
		dsi_dev[sel]->dsi_cmd_ctl.bits.dcs_sw_1p_tx_lp = 0;
		dsi_dev[sel]->dsi_cmd_ctl.bits.dcs_sr_0p_tx_lp = 0;
		dsi_dev[sel]->dsi_cmd_ctl.bits.max_rd_pkg_size_lp = 0;
		dsi_dev[sel]->dsi_cmd_ctl.bits.gen_lw_tx_lp = 0;
		dsi_dev[sel]->dsi_cmd_ctl.bits.dcs_lw_tx_lp = 0;
		dsi_dev[sel]->dsi_cmd_ctl.bits.cmd_mode_en = 1;
		dsi_dev[sel]->dsi_vid_ctl0.bits.video_mode_en = 0;
		dsi_dev[sel]->dsi_cfg1.bits.dpi_src = 0;
		dsi_dev[sel]->dsi_cfg2.bits.dbi_src = 1;
	} else {
		dsi_dev[sel]->dsi_cmd_ctl.bits.cmd_mode_en = 0;
		dsi_dev[sel]->dsi_vid_ctl0.bits.video_mode_en = 1;
		dsi_dev[sel]->dsi_cfg1.bits.dpi_src = 1;
	}

	return 0;
}

__s32 dsi_close(__u32 sel)
{
	dsi_dev[sel]->dsi_cfg1.bits.dpi_src = 0;
	dsi_delay_ms(16);
	dsi_dev[sel]->dsi_vid_ctl0.bits.video_mode_en = 0;
	dsi_dev[sel]->dsi_cmd_ctl.bits.cmd_mode_en = 1;
	dsi_hs_clk(sel, 0);
	dsi_delay_ms(5);
	dsi_dev[sel]->dsi_ctl0.bits.module_en = 0; /*shutdown dsi module*/
	return 0;
}

/**
 * @name       dsi_mode_switch
 * @brief      switch dsi mode between cmd and video mode
 * @param[IN]  sel: dsi module index; en:1-->video mode
 *             0--> cmd mode
 * @return	   alway return 0
 */
__s32 dsi_mode_switch(__u32 sel, __u32 cmd_en, __u32 lp_en)
{
	/*for video mode only*/
	/*switch between low power mode and high speed mode*/
	dsi_dev[sel]->dsi_cmd_ctl.bits.gen_sw_0p_tx_lp = lp_en;
	dsi_dev[sel]->dsi_cmd_ctl.bits.gen_sw_1p_tx_lp = lp_en;
	dsi_dev[sel]->dsi_cmd_ctl.bits.gen_sw_2p_tx_lp = lp_en;
	dsi_dev[sel]->dsi_cmd_ctl.bits.gen_sr_0p_tx_lp = lp_en;
	dsi_dev[sel]->dsi_cmd_ctl.bits.gen_sr_1p_tx_lp = lp_en;
	dsi_dev[sel]->dsi_cmd_ctl.bits.gen_sr_2p_tx_lp = lp_en;
	dsi_dev[sel]->dsi_cmd_ctl.bits.dcs_sw_0p_tx_lp = lp_en;
	dsi_dev[sel]->dsi_cmd_ctl.bits.dcs_sw_1p_tx_lp = lp_en;
	dsi_dev[sel]->dsi_cmd_ctl.bits.dcs_sr_0p_tx_lp = lp_en;
	dsi_dev[sel]->dsi_cmd_ctl.bits.max_rd_pkg_size_lp = lp_en;
	dsi_dev[sel]->dsi_cmd_ctl.bits.gen_lw_tx_lp = lp_en;
	dsi_dev[sel]->dsi_cmd_ctl.bits.dcs_lw_tx_lp = lp_en;

	/*command mode use dbi interface*/
	/*video mode use dpi interface*/
	if (cmd_en) {
		dsi_dev[sel]->dsi_cfg1.bits.dpi_src = 0;
		dsi_delay_ms(16);
		dsi_dev[sel]->dsi_vid_ctl0.bits.video_mode_en = 0;
		dsi_dev[sel]->dsi_cmd_ctl.bits.cmd_mode_en = 1;
	} else {
		dsi_dev[sel]->dsi_cmd_ctl.bits.cmd_mode_en = 0;
		dsi_dev[sel]->dsi_vid_ctl0.bits.video_mode_en = 1;
		dsi_dev[sel]->dsi_cfg1.bits.dpi_src = 1;
	}
	return 0;
}

__s32 dsi_tri_start(__u32 sel)
{
	return 0;
}

__s32 dsi_dcs_wr(__u32 sel, __u8 cmd, __u8 *para_p, __u32 para_num)
{
	__u8 dt, data0, data1;
	__u8 vc = 0;

	switch (para_num) {
	case 0:
		dt = DSI_DT_DCS_WR_P0;
		data0 = cmd;
		data1 = 0;
		break;
	case 1:
		dt = DSI_DT_DCS_WR_P1;
		data0 = cmd;
		data1 = *para_p;
		break;
	default:
		dt = DSI_DT_DCS_LONG_WR;
		data0 = ((para_num + 1) >> 0) & 0xff;
		data1 = ((para_num + 1) >> 8) & 0xff;
		break;
	}

	if (para_num > 1) {
		__u32 i = 0;

		dsi_dev[sel]->dsi_pkg_ctl1.dwval =
		    *(para_p + i + 2) << 24 | *(para_p + i + 1) << 16 |
		    *(para_p + i + 0) << 8 | cmd << 0;
		i += 3;
		while (i < para_num) {
			dsi_dev[sel]->dsi_pkg_ctl1.dwval =
			    *(para_p + i + 3) << 24 | *(para_p + i + 2) << 16 |
			    *(para_p + i + 1) << 8 | *(para_p + i + 0) << 0;
			i += 4;
		};
	}

	dsi_dev[sel]->dsi_pkg_ctl0.dwval =
	    (data1 << 16 | data0 << 8 | vc << 6 | dt);
	dsi_delay_us(20 + para_num);
	return 0;
}

__s32 dsi_dcs_wr_index(__u32 sel, __u8 index)
{
	return 0;
}

__s32 dsi_dcs_wr_data(__u32 sel, __u8 data)
{

	return 0;
}

__s32 dsi_dcs_wr_0para(__u32 sel, __u8 cmd)
{
	__u8 tmp;

	dsi_dcs_wr(0, cmd, &tmp, 0);
	return 0;
}

__s32 dsi_dcs_wr_1para(__u32 sel, __u8 cmd, __u8 para)
{
	__u8 tmp = para;

	dsi_dcs_wr(0, cmd, &tmp, 1);
	return 0;
}

__s32 dsi_dcs_wr_2para(__u32 sel, __u8 cmd, __u8 para1, __u8 para2)
{
	__u8 tmp[2];

	tmp[0] = para1;
	tmp[1] = para2;
	dsi_dcs_wr(0, cmd, tmp, 2);
	return 0;
}

__s32 dsi_dcs_wr_3para(__u32 sel, __u8 cmd, __u8 para1, __u8 para2, __u8 para3)
{
	__u8 tmp[3];

	tmp[0] = para1;
	tmp[1] = para2;
	tmp[2] = para3;
	dsi_dcs_wr(0, cmd, tmp, 3);
	return 0;
}
__s32 dsi_dcs_wr_4para(__u32 sel, __u8 cmd, __u8 para1, __u8 para2, __u8 para3,
		       __u8 para4)
{
	__u8 tmp[4];

	tmp[0] = para1;
	tmp[1] = para2;
	tmp[2] = para3;
	tmp[3] = para4;
	dsi_dcs_wr(0, cmd, tmp, 4);
	return 0;
}

__s32 dsi_dcs_wr_5para(__u32 sel, __u8 cmd, __u8 para1, __u8 para2, __u8 para3,
		       __u8 para4, __u8 para5)
{
	__u8 tmp[5];

	tmp[0] = para1;
	tmp[1] = para2;
	tmp[2] = para3;
	tmp[3] = para4;
	tmp[4] = para5;
	dsi_dcs_wr(0, cmd, tmp, 5);
	return 0;
}

__s32 dsi_dcs_wr_memory(__u32 sel, __u32 *p_data, __u32 length)
{
	__u32 tx_cntr = length;
	__u32 tx_num;
	__u32 *tx_p = p_data;
	__u8 para[256];
	__u32 i;
	__u32 start = 1;

	while (tx_cntr) {
		if (tx_cntr >= 83)
			tx_num = 83;
		else
			tx_num = tx_cntr;
		tx_cntr -= tx_num;

		for (i = 0; i < tx_num; i++) {
			para[i * 3 + 0] = (*tx_p >> 16) & 0xff;
			para[i * 3 + 1] = (*tx_p >> 8) & 0xff;
			para[i * 3 + 2] = (*tx_p >> 0) & 0xff;
			tx_p++;
		}

		if (start) {
			dsi_dcs_wr(sel, DSI_DCS_WRITE_MEMORY_START, para,
				   tx_num * 3);
			start = 0;
		} else {
			dsi_dcs_wr(sel, DSI_DCS_WRITE_MEMORY_CONTINUE, para,
				   tx_num * 3);
		}
	}
	return 0;
}

__s32 dsi_gen_wr(__u32 sel, __u8 cmd, __u8 *para_p, __u32 para_num)
{
	__u8 dt, data0, data1;

	switch (para_num) {
	case 0:
		dt = DSI_DT_GEN_WR_P1;
		data0 = cmd;
		data1 = 0;
		break;
	case 1:
		dt = DSI_DT_GEN_WR_P2;
		data0 = cmd;
		data1 = *para_p;
		break;
	default:
		dt = DSI_DT_GEN_LONG_WR;
		data0 = ((para_num + 1) >> 0) & 0xff;
		data1 = ((para_num + 1) >> 8) & 0xff;
		break;
	}

	if (para_num > 1) {
		__u32 i = 0;

		dsi_dev[sel]->dsi_pkg_ctl1.dwval =
		    *(para_p + i + 2) << 24 | *(para_p + i + 1) << 16 |
		    *(para_p + i + 0) << 8 | cmd << 0;
		i += 3;
		while (i < para_num) {
			dsi_dev[sel]->dsi_pkg_ctl1.dwval =
			    *(para_p + i + 3) << 24 | *(para_p + i + 2) << 16 |
			    *(para_p + i + 1) << 8 | *(para_p + i + 0) << 0;
			i += 4;
		};
	}

	dsi_dev[sel]->dsi_pkg_ctl0.dwval = (data1 << 16 | data0 << 8 | dt);
	dsi_delay_us(20 + para_num);
	return 0;
}

__s32 dsi_gen_wr_0para(__u32 sel, __u8 cmd)
{
	__u8 tmp;

	dsi_gen_wr(sel, cmd, &tmp, 0);
	return 0;
}

__s32 dsi_gen_wr_1para(__u32 sel, __u8 cmd, __u8 para)
{
	__u8 tmp = para;

	dsi_gen_wr(sel, cmd, &tmp, 1);
	return 0;
}

__s32 dsi_gen_wr_2para(__u32 sel, __u8 cmd, __u8 para1, __u8 para2)
{
	__u8 tmp[2];

	tmp[0] = para1;
	tmp[1] = para2;
	dsi_gen_wr(sel, cmd, tmp, 2);
	return 0;
}

__s32 dsi_gen_wr_3para(__u32 sel, __u8 cmd, __u8 para1, __u8 para2, __u8 para3)
{
	__u8 tmp[3];

	tmp[0] = para1;
	tmp[1] = para2;
	tmp[2] = para3;
	dsi_gen_wr(sel, cmd, tmp, 3);
	return 0;
}
__s32 dsi_gen_wr_4para(__u32 sel, __u8 cmd, __u8 para1, __u8 para2, __u8 para3,
		       __u8 para4)
{
	__u8 tmp[4];

	tmp[0] = para1;
	tmp[1] = para2;
	tmp[2] = para3;
	tmp[3] = para4;
	dsi_gen_wr(sel, cmd, tmp, 4);
	return 0;
}

__s32 dsi_gen_wr_5para(__u32 sel, __u8 cmd, __u8 para1, __u8 para2, __u8 para3,
		       __u8 para4, __u8 para5)
{
	__u8 tmp[5];

	tmp[0] = para1;
	tmp[1] = para2;
	tmp[2] = para3;
	tmp[3] = para4;
	tmp[4] = para5;
	dsi_gen_wr(sel, cmd, tmp, 5);
	return 0;
}

__s32 dsi_turn_on_peripheral_command(__u32 sel)
{
	dsi_dev[sel]->dsi_cfg1.bits.dpi_src = 1;
	dsi_dev[sel]->dsi_cfg1.bits.dpi_color_mode = 1;
	dsi_delay_ms(10);
	dsi_dev[sel]->dsi_cfg1.bits.dpi_color_mode = 0;

	return 0;
}

__s32 dsi_set_max_ret_size(__u32 sel, __u32 size)
{
	__u8 vc = 0;
	__u8 dt = DSI_DT_MAX_RET_SIZE;

	dsi_dev[sel]->dsi_pkg_ctl0.dwval =
	    (((size >> 8) & 0xff) << 16 | ((size >> 0) & 0xff) << 8 | vc << 6 |
	     dt);
	while (!dsi_dev[sel]->dsi_pkg_status.bits.fifo_pld_w_empty)
		;
	return 0;
}

/**
 * @name       :dsi_dcs_rd
 * @brief      :dcs read
 * @param[IN]  :sel:index of dsi
 * @param[IN]  :cmd: dcs command
 * @param[OUT] :result: pointer of read result,larger then max ret size
 * @param[OUT] :num_p: number of bytes have been readed
 * @return     :number of bytes have been readed
 */
__s32 dsi_dcs_rd(__u32 sel, __u8 cmd, __u8 *result, __u32 *num_p)
{
	__s32 ret = 0;
	__u8 dt = DSI_DT_DCS_RD_P0;
	u32 tmp_result = 0;

	dsi_dev[sel]->dsi_pkg_ctl2.bits.bta_en = 1;

	dsi_dev[sel]->dsi_pkg_ctl0.dwval =
	    (0 << 16 | cmd << 8 | 0 << 6 | dt);

	while (!dsi_dev[sel]->dsi_pkg_status.bits.fifo_pld_w_empty)
		;
	while (dsi_dev[sel]->dsi_pkg_status.bits.rd_cmd_busy)
		;

	while (!dsi_dev[sel]->dsi_pkg_status.bits.fifo_pld_r_empty) {
		tmp_result = dsi_dev[sel]->dsi_pkg_ctl1.dwval;
		result[0+ret] = (tmp_result >> 0) & 0xff;
		result[1+ret] = (tmp_result >> 8) & 0xff;
		result[2+ret] = (tmp_result >> 16) & 0xff;
		result[3+ret] = (tmp_result >> 24) & 0xff;
		ret += 4;
	}
	dsi_dev[sel]->dsi_pkg_ctl2.bits.bta_en = 0;
	*num_p = ret;

	return ret;
}

/**
 * @name       :dsi_gen_short_rd
 * @brief      :dsi generic short read with up to 2 para
 * @param[IN]  :dt:data type
 * @param[IN]  :para_p:device address,array,larger then max ret size
 * @param[IN]  :para_num:number of para_p array
 * @param[OUT] :result,array which store the result
 * @return     :number of bytes have been readed
 */
__s32 dsi_gen_short_rd(__u32 sel, __u8 *para_p, __u8 para_num, __u8 *result)
{
	__s32 ret = 0;
	__u8 data0 = 0;
	__u8 data1 = 0;
	__u32 vc = 0;
	__u8 dt = 0;
	u32 tmp_result = 0;

	switch (para_num) {
	case 0:
		dt = DSI_DT_GEN_RD_P0;
		break;
	case 1:
		dt = DSI_DT_GEN_RD_P1;
		data0 = para_p[0];
		break;
	case 2:
		dt = DSI_DT_GEN_RD_P2;
		data0 = para_p[0];
		data1 = para_p[1];
		break;
	default:
		dt = DSI_DT_GEN_RD_P2;
		data0 = para_p[0];
		data1 = para_p[1];
		break;
	}

	dsi_dev[sel]->dsi_pkg_ctl2.bits.bta_en = 1;

	dsi_dev[sel]->dsi_pkg_ctl0.dwval =
	    (data1 << 16 | data0 << 8 | vc << 6 | dt);

	while (!dsi_dev[sel]->dsi_pkg_status.bits.fifo_pld_w_empty)
		;
	while (dsi_dev[sel]->dsi_pkg_status.bits.rd_cmd_busy)
		;

	while (!dsi_dev[sel]->dsi_pkg_status.bits.fifo_pld_r_empty) {
		tmp_result = dsi_dev[sel]->dsi_pkg_ctl1.dwval;
		result[0+ret] = (tmp_result >> 0) & 0xff;
		result[1+ret] = (tmp_result >> 8) & 0xff;
		result[2+ret] = (tmp_result >> 16) & 0xff;
		result[3+ret] = (tmp_result >> 24) & 0xff;
		ret += 4;
	}
	dsi_dev[sel]->dsi_pkg_ctl2.bits.bta_en = 0;

	return ret;
}

__s32 dsi_dcs_rd_memory(__u32 sel, __u32 *p_data, __u32 length)
{
	return 0;
}

__s32 dsi_hs_clk(__u32 sel, __u32 on_off)
{
	if (on_off) {
		if (!dsi_dev[sel]->dsi_phy_status.bits.phy_ck_stop) {
			dsi_delay_ms(5);
			if (!dsi_dev[sel]->dsi_phy_status.bits.phy_ck_stop)
				__wrn("dsi clk enable error\n");
		}

		dsi_dev[sel]->dsi_ctl1.bits.phy_clk_lane_enable = 1;
	} else {
		dsi_dev[sel]->dsi_ctl1.bits.phy_clk_lane_enable = 0;
		if (!dsi_dev[sel]->dsi_phy_status.bits.phy_ck_stop) {
			dsi_delay_ms(5);
			if (!dsi_dev[sel]->dsi_phy_status.bits.phy_ck_stop)
				__wrn("dsi clk disable error\n");
		}
	}
	return 0;
}

__s32 dsi_dphy_cfg_0data(__u32 sel, __u32 code)
{
	dsi_delay_us(5);
	dsi_dev[sel]->dsi_phy_ctl3.bits.phy_cfg_en = 1;
	dsi_delay_us(1);
	dsi_dev[sel]->dsi_phy_ctl3.bits.phy_cfg_clk = 1;
	dsi_delay_us(1);
	dsi_dev[sel]->dsi_phy_ctl3.dwval =
	    ((dsi_dev[sel]->dsi_phy_ctl3.dwval) & (~0x00ff0000)) | (code << 16);
	dsi_delay_us(1);
	dsi_dev[sel]->dsi_phy_ctl3.bits.phy_cfg_clk = 0;
	dsi_delay_us(1);
	dsi_dev[sel]->dsi_phy_ctl3.bits.phy_cfg_en = 0;
	dsi_delay_us(5);
	return 0;
}

__s32 dsi_dphy_cfg_1data(__u32 sel, __u32 code, __u32 data)
{
	dsi_delay_us(5);
	dsi_dev[sel]->dsi_phy_ctl3.bits.phy_cfg_en = 1;
	dsi_delay_us(1);
	dsi_dev[sel]->dsi_phy_ctl3.bits.phy_cfg_clk = 1;
	dsi_delay_us(1);
	dsi_dev[sel]->dsi_phy_ctl3.dwval =
	    ((dsi_dev[sel]->dsi_phy_ctl3.dwval) & (~0x00ff0000)) | (code << 16);
	dsi_delay_us(1);
	dsi_dev[sel]->dsi_phy_ctl3.bits.phy_cfg_clk = 0;
	dsi_delay_us(1);
	dsi_dev[sel]->dsi_phy_ctl3.bits.phy_cfg_en = 0;
	dsi_delay_us(1);
	dsi_dev[sel]->dsi_phy_ctl3.dwval =
	    ((dsi_dev[sel]->dsi_phy_ctl3.dwval) & (~0x00ff0000)) | (data << 16);
	dsi_delay_us(1);
	dsi_dev[sel]->dsi_phy_ctl3.bits.phy_cfg_clk = 1;
	dsi_delay_us(1);
	dsi_dev[sel]->dsi_phy_ctl3.bits.phy_cfg_clk = 0;
	dsi_delay_us(5);
	return 0;
}

__s32 dsi_dphy_cfg_2data(__u32 sel, __u32 code, __u32 data0, __u32 data1)
{
	dsi_delay_us(5);
	dsi_dev[sel]->dsi_phy_ctl3.bits.phy_cfg_en = 1;
	dsi_delay_us(1);
	dsi_dev[sel]->dsi_phy_ctl3.bits.phy_cfg_clk = 1;
	dsi_delay_us(1);
	dsi_dev[sel]->dsi_phy_ctl3.dwval =
	    ((dsi_dev[sel]->dsi_phy_ctl3.dwval) & (~0x00ff0000)) | (code << 16);
	dsi_delay_us(1);
	dsi_dev[sel]->dsi_phy_ctl3.bits.phy_cfg_clk = 0;
	dsi_delay_us(1);
	dsi_dev[sel]->dsi_phy_ctl3.bits.phy_cfg_en = 0;
	dsi_delay_us(1);
	dsi_dev[sel]->dsi_phy_ctl3.dwval =
	    ((dsi_dev[sel]->dsi_phy_ctl3.dwval) & (~0x00ff0000)) |
	    (data0 << 16);
	dsi_delay_us(1);
	dsi_dev[sel]->dsi_phy_ctl3.bits.phy_cfg_clk = 1;
	dsi_delay_us(1);
	dsi_dev[sel]->dsi_phy_ctl3.bits.phy_cfg_clk = 0;
	dsi_delay_us(1);
	dsi_dev[sel]->dsi_phy_ctl3.dwval =
	    ((dsi_dev[sel]->dsi_phy_ctl3.dwval) & (~0x00ff0000)) |
	    (data1 << 16);
	dsi_delay_us(1);
	dsi_dev[sel]->dsi_phy_ctl3.bits.phy_cfg_clk = 1;
	dsi_delay_us(1);
	dsi_dev[sel]->dsi_phy_ctl3.bits.phy_cfg_clk = 0;
	dsi_delay_us(5);
	return 0;
}

static __s32 dsi_dphy_cfg_hsfrq(__u32 sel, __u32 hs_frq)
{
	__u32 hs_frq_set;
	__u32 hs_frq_tmp;

	hs_frq_tmp = hs_frq;

	if ((hs_frq_tmp >= 80) && (hs_frq_tmp < 90))
		hs_frq_set = 0x00;
	else if ((hs_frq_tmp >= 90) && (hs_frq_tmp < 100))
		hs_frq_set = 0x10;
	else if ((hs_frq_tmp >= 100) && (hs_frq_tmp < 110))
		hs_frq_set = 0x20;
	else if ((hs_frq_tmp >= 110) && (hs_frq_tmp < 130))
		hs_frq_set = 0x01;
	else if ((hs_frq_tmp >= 130) && (hs_frq_tmp < 140))
		hs_frq_set = 0x11;
	else if ((hs_frq_tmp >= 140) && (hs_frq_tmp < 150))
		hs_frq_set = 0x21;
	else if ((hs_frq_tmp >= 150) && (hs_frq_tmp < 170))
		hs_frq_set = 0x02;
	else if ((hs_frq_tmp >= 170) && (hs_frq_tmp < 180))
		hs_frq_set = 0x12;
	else if ((hs_frq_tmp >= 180) && (hs_frq_tmp < 200))
		hs_frq_set = 0x22;
	else if ((hs_frq_tmp >= 200) && (hs_frq_tmp < 220))
		hs_frq_set = 0x03;
	else if ((hs_frq_tmp >= 220) && (hs_frq_tmp < 240))
		hs_frq_set = 0x13;
	else if ((hs_frq_tmp >= 240) && (hs_frq_tmp < 250))
		hs_frq_set = 0x23;
	else if ((hs_frq_tmp >= 250) && (hs_frq_tmp < 270))
		hs_frq_set = 0x04;
	else if ((hs_frq_tmp >= 270) && (hs_frq_tmp < 300))
		hs_frq_set = 0x14;
	else if ((hs_frq_tmp >= 300) && (hs_frq_tmp < 330))
		hs_frq_set = 0x05;
	else if ((hs_frq_tmp >= 330) && (hs_frq_tmp < 360))
		hs_frq_set = 0x15;
	else if ((hs_frq_tmp >= 360) && (hs_frq_tmp < 400))
		hs_frq_set = 0x25;
	else if ((hs_frq_tmp >= 400) && (hs_frq_tmp < 450))
		hs_frq_set = 0x06;
	else if ((hs_frq_tmp >= 450) && (hs_frq_tmp < 500))
		hs_frq_set = 0x16;
	else if ((hs_frq_tmp >= 500) && (hs_frq_tmp < 550))
		hs_frq_set = 0x07;
	else if ((hs_frq_tmp >= 550) && (hs_frq_tmp < 600))
		hs_frq_set = 0x17;
	else if ((hs_frq_tmp >= 600) && (hs_frq_tmp < 650))
		hs_frq_set = 0x08;
	else if ((hs_frq_tmp >= 650) && (hs_frq_tmp < 700))
		hs_frq_set = 0x18;
	else if ((hs_frq_tmp >= 700) && (hs_frq_tmp < 750))
		hs_frq_set = 0x09;
	else if ((hs_frq_tmp >= 750) && (hs_frq_tmp < 800))
		hs_frq_set = 0x19;
	else if ((hs_frq_tmp >= 800) && (hs_frq_tmp < 850))
		hs_frq_set = 0x29;
	else if ((hs_frq_tmp >= 850) && (hs_frq_tmp < 900))
		hs_frq_set = 0x39;
	else if ((hs_frq_tmp >= 900) && (hs_frq_tmp < 950))
		hs_frq_set = 0x0a;
	else if ((hs_frq_tmp >= 950) && (hs_frq_tmp < 1000))
		hs_frq_set = 0x1a;
	else if ((hs_frq_tmp >= 1000) && (hs_frq_tmp < 1050))
		hs_frq_set = 0x2a;
	else if ((hs_frq_tmp >= 1050) && (hs_frq_tmp < 1100))
		hs_frq_set = 0x3a;
	else if ((hs_frq_tmp >= 1100) && (hs_frq_tmp < 1150))
		hs_frq_set = 0x0b;
	else if ((hs_frq_tmp >= 1150) && (hs_frq_tmp < 1200))
		hs_frq_set = 0x1b;
	else if ((hs_frq_tmp >= 1200) && (hs_frq_tmp < 1250))
		hs_frq_set = 0x2b;
	else if ((hs_frq_tmp >= 1250) && (hs_frq_tmp < 1300))
		hs_frq_set = 0x3b;
	else if ((hs_frq_tmp >= 1300) && (hs_frq_tmp < 1350))
		hs_frq_set = 0x0c;
	else if ((hs_frq_tmp >= 1350) && (hs_frq_tmp < 1400))
		hs_frq_set = 0x1c;
	else if ((hs_frq_tmp >= 1400) && (hs_frq_tmp < 1450))
		hs_frq_set = 0x2c;
	else if ((hs_frq_tmp >= 1450) && (hs_frq_tmp < 1500))
		hs_frq_set = 0x3c;
	else
		hs_frq_set = 0x00;

	dsi_dphy_cfg_1data(sel, 0x44, hs_frq_set << 1);
	return 0;
}

static __s32 dsi_dphy_cfg_pll(__u32 sel, __u32 m, __u32 n)
{
	dsi_dphy_cfg_1data(sel, 0x19, 0x30);
	dsi_dphy_cfg_1data(sel, 0x17, n - 1);
	dsi_dphy_cfg_1data(sel, 0x18, 0x7f & (((m - 1) >> 0) & 0x1f));
	dsi_dphy_cfg_1data(sel, 0x18, 0x80 | (((m - 1) >> 5) & 0x0f));
	return 0;
}

static __s32 dsi_dphy_cfg(__u32 sel, disp_panel_para *panel)
{
	/*Input sequence:
	1.Set RSTZ = 1'b0.
	2.Set SHUTDOWNZ = 1'b0.
	3.Set TESTCLEAR = 1'b1.
	4.Set MASTERSLAVEZ = 1'b1 (for MASTER) / 1'b0 (for SLAVE).
	5.Set BASEDIRX to the desired values.
	6.Set all REQUEST inputs to zero.
	7.Wait for t > Tmin.
	8.Set RSTZ = 1'b1.
	9.Set SHUTDOWNZ = 1'b1.
	10.Set TESTCLEAR = 1'b0.
	*/
	__u32 mode, lane, format, dclk;
	u32 timing_div = 1;

	if (panel->lcd_if == LCD_IF_DSI &&
	    panel->lcd_tcon_mode == DISP_TCON_DUAL_DSI)
		timing_div = 2;

	mode = panel->lcd_dsi_if;
	lane = panel->lcd_dsi_lane;
	format = panel->lcd_dsi_format;
	dclk = panel->lcd_dclk_freq / timing_div;

	dsi_dev[sel]->dsi_cfg3.bits.reg_rext = 0;
	dsi_dev[sel]->dsi_cfg3.bits.reg_snk = 2;
	dsi_dev[sel]->dsi_cfg3.bits.reg_rint = 2;
	dsi_delay_ms(1);
	dsi_dev[sel]->dsi_cfg3.bits.enrext = 1;
	dsi_delay_ms(1);

	dsi_dev[sel]->dsi_phy_ctl3.bits.phy_cfg_clr = 1;
	dsi_delay_ms(1);
	dsi_dev[sel]->dsi_ctl1.bits.phy_rst = 0;
	dsi_delay_ms(1);
	dsi_dev[sel]->dsi_ctl1.bits.phy_en = 0;
	dsi_delay_ms(1);
	dsi_dev[sel]->dsi_phy_ctl3.bits.phy_cfg_clr = 0;
	dsi_delay_ms(1);

	if (panel->lcd_dsi_if != LCD_DSI_IF_COMMAND_MODE) {
		dsi_dphy_cfg_1data(sel, 0x20, 0xcd);
		dsi_dphy_cfg_1data(sel, 0x22, 0x42);
	}

	if (LCD_DSI_IF_VIDEO_MODE == mode || LCD_DSI_IF_BURST_MODE == mode) {
		dsi_dphy_cfg_hsfrq(sel,
				   dclk * dsi_bits_per_pixel[format] / lane);
		dsi_dphy_cfg_pll(sel, dsi_bits_per_pixel[format] * 2, lane * 2);
		dsi_dphy_cfg_0data(sel, 0x00);
	} else {
		__u32 n = dclk * 6 / 30;

		dsi_dphy_cfg_hsfrq(sel, dclk * 36);
		dsi_dphy_cfg_pll(sel, 6 * n, n);
		dsi_dphy_cfg_0data(sel, 0x00);
	}

	dsi_delay_ms(1);
	dsi_dev[sel]->dsi_ctl1.bits.phy_rst = 1;
	dsi_delay_ms(1);
	dsi_dev[sel]->dsi_ctl1.bits.phy_clk_gating = 1;
	dsi_delay_ms(1);
	dsi_dev[sel]->dsi_ctl1.bits.phy_en = 1;
	dsi_delay_ms(1);
	dsi_dev[sel]->dsi_phy_ctl1.bits.phy_stop_set = 1;
	dsi_dev[sel]->dsi_ctl1.bits.phy_lane_num = lane - 1;
	return 0;
}

__u32 dsi_io_open(__u32 sel, disp_panel_para *panel)
{
	dsi_dphy_cfg(sel, panel);
	return 0;
}

__u32 dsi_io_close(__u32 sel)
{
	dsi_dev[sel]->dsi_ctl1.bits.phy_clk_gating = 0;
	dsi_delay_ms(1);
	dsi_dev[sel]->dsi_ctl1.bits.phy_rst = 0;
	dsi_delay_ms(1);
	dsi_dev[sel]->dsi_ctl1.bits.phy_en = 0;
	dsi_delay_ms(1);
	dsi_dev[sel]->dsi_phy_ctl3.bits.phy_cfg_clr = 0;
	dsi_delay_ms(1);

	return 0;
}

__s32 dsi_clk_enable(__u32 sel, __u32 en)
{
	dsi_hs_clk(sel, en);
	return 0;
}

static __s32 dsi_basic_cfg(__u32 sel, disp_panel_para *panel)
{
	__u32 mode, lane, format, dclk;
	u32 timing_div = 1;

	if (panel->lcd_if == LCD_IF_DSI &&
	    panel->lcd_tcon_mode == DISP_TCON_DUAL_DSI)
		timing_div = 2;

	mode = panel->lcd_dsi_if;
	lane = panel->lcd_dsi_lane;
	format = panel->lcd_dsi_format;
	dclk = panel->lcd_dclk_freq / timing_div;

	dsi_dev[sel]->dsi_ctl0.bits.module_en = 1;
	if (LCD_DSI_IF_VIDEO_MODE == mode || LCD_DSI_IF_BURST_MODE == mode) {
		dsi_dev[sel]->dsi_ctl2.dwval =
		    ((dclk * dsi_bits_per_pixel[format] + 4 * lane * 10) /
		     (8 * lane * 10)) &
		    0xff;
		dsi_delay_ms(100);
		dsi_dev[sel]->dsi_to_ctl0.dwval =
		    ((dclk * dsi_bits_per_pixel[format] + 4 * lane * 10) /
		     (8 * lane * 10)) &
		    0xff;
	} else {
		dsi_dev[sel]->dsi_ctl2.dwval =
		    ((dclk * 36) / (8 * lane * 10)) & 0xff;
		dsi_delay_ms(100);
		dsi_dev[sel]->dsi_to_ctl0.dwval =
		    ((dclk * 36) / (8 * lane * 10)) & 0xff;
	}
	dsi_dev[sel]->dsi_pkg_ctl2.bits.eotp_tx_en = 0;
	dsi_dev[sel]->dsi_pkg_ctl2.bits.eotp_rx_en = 0;
	dsi_dev[sel]->dsi_pkg_ctl2.bits.bta_en = 0;
	dsi_dev[sel]->dsi_pkg_ctl2.bits.ecc_rx_en = 0;
	dsi_dev[sel]->dsi_pkg_ctl2.bits.crc_rx_en = 0;
	dsi_dev[sel]->dsi_pkg_ctl2.bits.vid_rx = 0;
	dsi_dev[sel]->dsi_vid_ctl2.dwval = (panel->lcd_x / timing_div * 3 / 4)
					   << 16;
	dsi_dev[sel]->dsi_phy_ctl1.dwval =
	    ((dsi_dev[sel]->dsi_phy_ctl1.dwval) & (~0x7fff0000)) |
	    ((panel->lcd_x / timing_div * 3 / 4) << 16);

	dsi_dev[sel]->dsi_phy_ctl0.dwval = 0x00140014;
	dsi_dev[sel]->dsi_to_ctl1.dwval = 0x0;

	dsi_dev[sel]->dsi_cfg0.bits.force_rx_0 = 0;
	dsi_dev[sel]->dsi_cfg0.bits.force_rx_1 = 0;
	dsi_dev[sel]->dsi_cfg0.bits.force_rx_2 = 0;
	dsi_dev[sel]->dsi_cfg0.bits.force_rx_3 = 0;
	dsi_dev[sel]->dsi_cfg0.bits.base_dir = 0;
	dsi_dev[sel]->dsi_ctl1.bits.phy_clk_lane_enable = 0;
	dsi_dev[sel]->dsi_phy_ctl2.bits.phy_ck_tx_ulps_req = 0;
	dsi_dev[sel]->dsi_phy_ctl2.bits.phy_ck_tx_ulps_exit = 0;
	dsi_dev[sel]->dsi_phy_ctl2.bits.phy_data_tx_ulps_req = 0;
	dsi_dev[sel]->dsi_phy_ctl2.bits.phy_data_tx_upls_exit = 0;
	dsi_dev[sel]->dsi_phy_ctl2.bits.phy_tx_triger = 0;

	dsi_dev[sel]->dsi_cmd_ctl.bits.gen_sw_0p_tx_lp = 1;
	dsi_dev[sel]->dsi_cmd_ctl.bits.gen_sw_1p_tx_lp = 1;
	dsi_dev[sel]->dsi_cmd_ctl.bits.gen_sw_2p_tx_lp = 1;
	dsi_dev[sel]->dsi_cmd_ctl.bits.gen_sr_0p_tx_lp = 1;
	dsi_dev[sel]->dsi_cmd_ctl.bits.gen_sr_1p_tx_lp = 1;
	dsi_dev[sel]->dsi_cmd_ctl.bits.gen_sr_2p_tx_lp = 1;
	dsi_dev[sel]->dsi_cmd_ctl.bits.dcs_sw_0p_tx_lp = 1;
	dsi_dev[sel]->dsi_cmd_ctl.bits.dcs_sw_1p_tx_lp = 1;
	dsi_dev[sel]->dsi_cmd_ctl.bits.dcs_sr_0p_tx_lp = 1;
	dsi_dev[sel]->dsi_cmd_ctl.bits.max_rd_pkg_size_lp = 1;
	dsi_dev[sel]->dsi_cmd_ctl.bits.gen_lw_tx_lp = 1;
	dsi_dev[sel]->dsi_cmd_ctl.bits.dcs_lw_tx_lp = 1;

	dsi_dev[sel]->dsi_cmd_ctl.bits.cmd_mode_en = 1;
	return 0;
}

static __s32 dsi_packet_cfg(__u32 sel, disp_panel_para *panel)
{
	u32 timing_div = 1;

	if (panel->lcd_if == LCD_IF_DSI &&
	    panel->lcd_tcon_mode == DISP_TCON_DUAL_DSI)
		timing_div = 2;
	if (panel->lcd_dsi_if == LCD_DSI_IF_COMMAND_MODE) {
		__u32 vc = 0;
		__u32 format = panel->lcd_dsi_format;
		__u32 x = panel->lcd_x / timing_div;

		dsi_dev[sel]->dsi_dbi_ctl0.bits.dbi_vid = vc;
		switch (format) {
		case 0:
			dsi_dev[sel]->dsi_dbi_ctl0.bits.dbi_in_format = 11;
			dsi_dev[sel]->dsi_dbi_ctl0.bits.dbi_out_format = 11;
			dsi_dev[sel]->dsi_dbi_ctl0.bits.lut_size_cfg = 2;
			break;
		case 1:
			dsi_dev[sel]->dsi_dbi_ctl0.bits.dbi_in_format = 9;
			dsi_dev[sel]->dsi_dbi_ctl0.bits.dbi_out_format = 9;
			dsi_dev[sel]->dsi_dbi_ctl0.bits.lut_size_cfg = 1;
			break;
		case 2:
			dsi_dev[sel]->dsi_dbi_ctl0.bits.dbi_in_format = 9;
			dsi_dev[sel]->dsi_dbi_ctl0.bits.dbi_out_format = 9;
			dsi_dev[sel]->dsi_dbi_ctl0.bits.lut_size_cfg = 1;
			break;
		case 3:
			dsi_dev[sel]->dsi_dbi_ctl0.bits.dbi_in_format = 8;
			dsi_dev[sel]->dsi_dbi_ctl0.bits.dbi_out_format = 8;
			dsi_dev[sel]->dsi_dbi_ctl0.bits.lut_size_cfg = 0;
			break;
		default:
			dsi_dev[sel]->dsi_dbi_ctl0.bits.dbi_in_format = 11;
			dsi_dev[sel]->dsi_dbi_ctl0.bits.dbi_out_format = 11;
			dsi_dev[sel]->dsi_dbi_ctl0.bits.lut_size_cfg = 2;
			break;
		}

		dsi_dev[sel]->dsi_dbi_ctl0.bits.partion_mode = 1;

		dsi_dev[sel]->dsi_dbi_ctl1.bits.allowed_cmd_size =
		    x * dsi_bits_per_pixel[format] / 8 + 1;
		dsi_dev[sel]->dsi_dbi_ctl1.bits.wr_cmd_size =
		    x * dsi_bits_per_pixel[format] / 8 + 1;

		dsi_dev[sel]->dsi_pkg_ctl2.bits.bta_en = 0;
		dsi_dev[sel]->dsi_cmd_ctl.bits.pkg_ack_req = 0;
		dsi_dev[sel]->dsi_cmd_ctl.bits.te_ack_en = 0;

		dsi_dev[sel]->dsi_cmd_ctl.bits.cmd_mode_en = 1;

		dsi_dev[sel]->dsi_cfg2.bits.dbi_rst = 1;
		dsi_dev[sel]->dsi_cfg2.bits.dbi_src = 1;
	} else {
		__u32 vc = 0;
		__u32 lane = panel->lcd_dsi_lane;
		__u32 format = panel->lcd_dsi_format;
		__u32 x = panel->lcd_x / timing_div;
		__u32 y = panel->lcd_y;
		__u32 ht = panel->lcd_ht / timing_div;
		__u32 hbp = panel->lcd_hbp / timing_div;
		__u32 hspw = panel->lcd_hspw / timing_div;
		__u32 vt = panel->lcd_vt;
		__u32 vbp = panel->lcd_vbp;
		__u32 vspw = panel->lcd_vspw;

		switch (format) {
		case 0:
			dsi_dev[sel]->dsi_cfg1.bits.dpi_src_format = 0;
			dsi_dev[sel]->dsi_dpi_cfg0.bits.dpi_format = 5;
			break;
		case 1:
			dsi_dev[sel]->dsi_cfg1.bits.dpi_src_format = 1;
			dsi_dev[sel]->dsi_dpi_cfg0.bits.dpi_format = 3;
			break;
		case 2:
			dsi_dev[sel]->dsi_cfg1.bits.dpi_src_format = 1;
			dsi_dev[sel]->dsi_dpi_cfg0.bits.dpi_format = 3;
			break;
		case 3:
			dsi_dev[sel]->dsi_cfg1.bits.dpi_src_format = 2;
			dsi_dev[sel]->dsi_dpi_cfg0.bits.dpi_format = 0;
			break;
		default:
			dsi_dev[sel]->dsi_cfg1.bits.dpi_src_format = 0;
			dsi_dev[sel]->dsi_dpi_cfg0.bits.dpi_format = 5;
			break;
		}

		dsi_dev[sel]->dsi_dpi_cfg0.bits.dpi_vid = vc;
		dsi_dev[sel]->dsi_dpi_cfg1.bits.de_ploarity = 0;
		dsi_dev[sel]->dsi_dpi_cfg1.bits.vsync_ploarity = 1;
		dsi_dev[sel]->dsi_dpi_cfg1.bits.hsync_ploarity = 1;
		dsi_dev[sel]->dsi_dpi_cfg1.bits.shutd_polarity = 0;
		dsi_dev[sel]->dsi_dpi_cfg1.bits.colorm_polarity = 0;
		dsi_dev[sel]->dsi_dpi_cfg0.bits.video_mode_format_18bit =
		    (format == 1) ? 1 : 0;
		if (panel->lcd_dsi_if == LCD_DSI_IF_VIDEO_MODE) {
			dsi_dev[sel]->dsi_vid_ctl0.bits.video_mode_cfg = 0;
			dsi_dev[sel]->dsi_vid_ctl0.bits.hfp_lp_en = 0;
		} else {
			dsi_dev[sel]->dsi_vid_ctl0.bits.video_mode_cfg = 2;
			dsi_dev[sel]->dsi_vid_ctl0.bits.hfp_lp_en = 1;
		}
		dsi_dev[sel]->dsi_vid_ctl0.bits.vsa_lp_en = 1;
		dsi_dev[sel]->dsi_vid_ctl0.bits.vbp_lp_en = 1;
		dsi_dev[sel]->dsi_vid_ctl0.bits.vfp_lp_en = 0;
		dsi_dev[sel]->dsi_vid_ctl0.bits.vact_lp_en = 1;
		dsi_dev[sel]->dsi_vid_ctl0.bits.hbp_lp_en = 1;

		dsi_dev[sel]->dsi_vid_ctl1.bits.pkt_multi_en = 0;
		dsi_dev[sel]->dsi_vid_ctl1.bits.pkt_null_in_hact = 0;
		dsi_dev[sel]->dsi_vid_ctl1.bits.bta_per_frame = 0;
		dsi_dev[sel]->dsi_vid_ctl1.bits.lp_cmd_en = 0;

		dsi_dev[sel]->dsi_vid_tim2.bits.pixels_per_pkg = x;
		dsi_dev[sel]->dsi_vid_ctl1.bits.pkt_num_per_line = 1;
		dsi_dev[sel]->dsi_vid_ctl1.bits.pkt_null_size = 0;

		dsi_dev[sel]->dsi_vid_tim3.bits.hsa =
		    hspw * dsi_bits_per_pixel[format] / (8 * lane);
		dsi_dev[sel]->dsi_vid_tim3.bits.hbp =
		    (hbp - hspw) * dsi_bits_per_pixel[format] / (8 * lane);
		dsi_dev[sel]->dsi_vid_tim2.bits.ht =
		    ht * dsi_bits_per_pixel[format] / (8 * lane);

		dsi_dev[sel]->dsi_vid_tim0.bits.vsa = vspw;
		dsi_dev[sel]->dsi_vid_tim0.bits.vbp = vbp - vspw;
		dsi_dev[sel]->dsi_vid_tim1.bits.vfp = vt - (vbp + y);
		dsi_dev[sel]->dsi_vid_tim1.bits.vact = y;

		dsi_dev[sel]->dsi_cfg1.bits.dpi_shut_down = 0;
		dsi_dev[sel]->dsi_cfg1.bits.dpi_color_mode = 0;
	}
	return 0;
}

__s32 dsi_cfg(__u32 sel, disp_panel_para *panel)
{
	dsi_irq_disable_all(sel);
	dsi_basic_cfg(sel, panel);
	dsi_packet_cfg(sel, panel);

	return 0;
}

__s32 dsi_exit(__u32 sel)
{
	return 0;
}

__u8 dsi_ecc_pro(__u32 dsi_ph)
{
	return 0;
}

__u16 dsi_crc_pro(__u8 *pd_p, __u32 pd_bytes)
{
	return 0;
}

__u16 dsi_crc_pro_pd_repeat(__u8 pd, __u32 pd_bytes)
{
	return 0;
}

EXPORT_SYMBOL(dsi_dcs_wr);
EXPORT_SYMBOL(dsi_dcs_wr_0para);
EXPORT_SYMBOL(dsi_dcs_wr_1para);
EXPORT_SYMBOL(dsi_dcs_wr_2para);
EXPORT_SYMBOL(dsi_dcs_wr_3para);
EXPORT_SYMBOL(dsi_dcs_wr_4para);
EXPORT_SYMBOL(dsi_dcs_wr_5para);

#endif
